<template>
<div>
    <div style="position:relative">
        <div :id="id" style="min-width:800px" :class="myClass"></div>
        <div v-if="showExpand">
            <div class="e-menu e-code" @click="editHTML">
                <Icon type="md-code-working" size="22" />
            </div>
            <div class="e-menu e-preview" @click="fullscreenModal=true">
                <Icon type="ios-eye" size="24" />
            </div>
            <div class="e-menu e-trash" @click="clear">
                <Icon type="md-trash" size="18" />
            </div>
        </div>
    </div>

    <Modal title="编辑html代码" v-model="showHTMLModal" :mask-closable="false" :width="900" :fullscreen="full" z-index="9999">
        <Input v-if="!full" v-model="dataEdit" :rows="15" type="textarea" style="max-height:60vh;overflow:auto;" />
        <Input v-if="full" v-model="dataEdit" :rows="32" type="textarea" />
        <div slot="footer">
            <Button @click="full=!full" icon="md-expand">全屏开/关</Button>
            <Button @click="editHTMLOk" type="primary" icon="md-checkmark-circle-outline">确定保存</Button>
        </div>
    </Modal>
    <Modal title="预览" v-model="fullscreenModal" fullscreen  z-index="9999">
        <div v-html="data">{{data}}</div>
        <div slot="footer">
            <Button @click="fullscreenModal=false">关闭</Button>
        </div>
    </Modal>
</div>
</template>

<script>
import {
    uploadFile
} from "@/api/index";
import E from "wangeditor";
import xss from "xss";
// 表情包配置 自定义表情可在该js文件中统一修改
import {
    sina
} from "@/libs/emoji";
var editor = null;
export default {
    name: "editor",
    props: {
        myClass: {
            type: String,
            default: 'editor'
        },
        id: {
            type: String,
            default: "editor"
        },
        value: String,
        base64: {
            type: Boolean,
            default: false
        },
        showExpand: {
            type: Boolean,
            default: true
        },
        openXss: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            editor: null,
            data: this.value, // 富文本数据
            dataEdit: "", // 编辑数据
            showHTMLModal: false, // 显示html
            full: false, // html全屏开关
            fullscreenModal: false // 显示全屏预览
        };
    },
    methods: {
        initEditor() {
            let that = this;
            // 详见wangeditor3官网文档 https://www.kancloud.cn/wangfupeng/wangeditor3/332599
            editor = new E(`#${this.id}`);
            // 编辑内容绑定数据
            editor.customConfig.onchange = html => {
                if (this.openXss) {
                    this.data = xss(html);
                } else {
                    this.data = html;
                }
                this.$emit("input", this.data);
                this.$emit("on-change", this.data);
            };
            // z-index
            editor.customConfig.zIndex = 100;
            if (this.base64) {
                // 使用 base64 保存图片
                editor.customConfig.uploadImgShowBase64 = true;
            } else {
                // 配置上传图片服务器端地址
                editor.customConfig.uploadImgServer = uploadFile;
                // hboot如要header中传入token鉴权
                editor.customConfig.uploadImgHeaders = {
                    accessToken: that.getStore("accessToken")
                };
				//图片大小限制为20M 默认为5M
				editor.customConfig.uploadImgMaxSize = 5*1024.*1024;
                editor.customConfig.uploadFileName = "file";
                editor.customConfig.uploadImgHooks = {
                    before: function (xhr, editor, files) {
                        // 图片上传之前触发
                    },
                    success: function (xhr, editor, result) {
                        // 图片上传并返回结果，图片插入成功之后触发
                    },
                    fail: function (xhr, editor, result) {
                        // 图片上传并返回结果，但图片插入错误时触发
                        that.$Message.error("上传图片失败");
                    },
                    error: function (xhr, editor) {
                        // 图片上传出错时触发
                        that.$Message.error("上传图片出错");
                    },
                    timeout: function (xhr, editor) {
                        // 图片上传超时时触发
                        that.$Message.error("上传图片超时");
                    },
                    // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式，可使用该配置
                    customInsert: function (insertImg, result, editor) {
                        if (result.success == true) {
                            let url = result.result;
                            insertImg(url);
                            that.$Message.success("上传图片成功");
                        } else {
                            that.$Message.error(result.message);
                        }
                    }
                };
            }
            editor.customConfig.customAlert = function (info) {
                // info 是需要提示的内容
                 that.$Message.info(info);
            };
            // 字体
            editor.customConfig.fontNames = ["微软雅黑", "Arial"];
            // 表情面板可以有多个 tab ，因此要配置成一个数组。数组每个元素代表一个 tab 的配置
            editor.customConfig.emotions = [{
                // tab 的标题
                title: "新浪",
                // type -> 'emoji' / 'image'
                type: "image",
                // content -> 数组
                content: sina
            }];
            editor.create();
            if (this.value) {
                if (this.openXss) {
                    editor.txt.html(xss(this.value));
                } else {
                    editor.txt.html(this.value);
                }
            }
        },
        editHTML() {
            this.dataEdit = this.data;
            this.showHTMLModal = true;
        },
        editHTMLOk() {
			this.data = this.dataEdit;
            editor.txt.html(this.dataEdit);
			
            this.$emit("input", this.data);
            this.$emit("on-change", this.data);
            this.showHTMLModal = false;
        },
        clear() {
            this.$Modal.confirm({
                title: "确认清空",
                content: "确认要清空编辑器内容？清空后不能撤回",
                onOk: () => {
                    this.data = "";
                    editor.txt.html(this.data);
                    this.$emit("input", this.data);
                    this.$emit("on-change", this.data);
                }
            });
        },
        setData(value) {
            if (!editor) {
                this.initEditor();
            }
            // if (value && value != this.data) {
            if (value != null && value != undefined && value != this.data) {
                this.data = value;
                editor.txt.html(this.data);
                this.$emit("input", this.data);
                this.$emit("on-change", this.data);
            }
        }
    },
    watch: {
        value(val) {
            this.setData(val);
        }
    },
    mounted() {
        this.initEditor();
    }
};
</script>

<style lang="less">
.e-menu {
    z-index: 101;
    position: absolute;
    cursor: pointer;
    color: #999;

    :hover {
        color: #333;
    }
}

.e-code {
    top: 4px;
    left: 692px;
}

.e-preview {
    top: 4px;
    left: 726px;
}

.e-trash {
    top: 6px;
    left: 760px;
}

/**
 * By: haley
 * Time: 2020-07-31 13:35:04
 * 如果将编辑器放置于非通栏的容器里，由于宽度有限，需要处理兼容性
 * 处理方法：在调用editor的时候，传入一个myClass=“editorInRight” 即可
 * <editor id="formAddContent" v-model.trim="formAdd.content" myClass="editorInRight"></editor>
 */


@media (min-width:1000px) {
    @width: 340px;

    .editorInRight {
        max-width: @width;
        min-width: @width !important;
    }

    .w-e-toolbar {
        flex-wrap: wrap;
    }

    @top: 62px;
    @gutter: 34px;
    @left: 48px+@gutter;
    @left2: @left+@gutter;
    @left3: @left2+@gutter;

    .editorInRight+div .e-menu {
        top: @top;
    }

    .editorInRight+div .e-code {
        left: @left;
        top: 4px+@top;
    }

    .editorInRight+div .e-preview {
        top: 4px+@top;
        left: @left2;
    }

    .editorInRight+div .e-trash {
        top: 6px+@top;
        left: @left3;
    }
}
@media (min-width:1200px) {
    @width: 470px;

    .editorInRight {
        max-width: @width;
        min-width: @width !important;
    }

    .w-e-toolbar {
        flex-wrap: wrap;
    }

    @top: 30px;
    @gutter: 34px;
    @left: 48px+@gutter*6;
    @left2: @left+@gutter;
    @left3: @left2+@gutter;

    .editorInRight+div .e-menu {
        top: @top;
    }

    .editorInRight+div .e-code {
        left: @left;
        top: 4px+@top;
    }

    .editorInRight+div .e-preview {
        top: 4px+@top;
        left: @left2;
    }

    .editorInRight+div .e-trash {
        top: 6px+@top;
        left: @left3;
    }
}
@media (min-width:1366px) {
    @width: 520px;

    .editorInRight {
        max-width: @width;
        min-width: @width !important;
    }

    .w-e-toolbar {
        flex-wrap: wrap;
    }

    @top: 30px;
    @gutter: 34px;
    @left: 48px+@gutter*5;
    @left2: @left+@gutter;
    @left3: @left2+@gutter;

    .editorInRight+div .e-menu {
        top: @top;
    }

    .editorInRight+div .e-code {
        left: @left;
        top: 4px+@top;
    }

    .editorInRight+div .e-preview {
        top: 4px+@top;
        left: @left2;
    }

    .editorInRight+div .e-trash {
        top: 6px+@top;
        left: @left3;
    }
}
@media (min-width:1440px) {
    @width: 570px;

    .editorInRight {
        max-width: @width;
        min-width: @width !important;
    }

    .w-e-toolbar {
        flex-wrap: wrap;
    }

    @top: 30px;
    @gutter: 34px;
    @left: 48px+@gutter*3;
    @left2: @left+@gutter;
    @left3: @left2+@gutter;

    .editorInRight+div .e-menu {
        top: @top;
    }

    .editorInRight+div .e-code {
        left: @left;
        top: 4px+@top;
    }

    .editorInRight+div .e-preview {
        top: 4px+@top;
        left: @left2;
    }

    .editorInRight+div .e-trash {
        top: 6px+@top;
        left: @left3;
    }
}
@media (min-width:1560px) {
    @width: 650px;

    .editorInRight {
        max-width: @width;
        min-width: @width !important;
    }

    .w-e-toolbar {
        flex-wrap: wrap;
    }

    @top: 30px;
    @gutter: 34px;
    @left: 48px+@gutter;
    @left2: @left+@gutter;
    @left3: @left2+@gutter;

    .editorInRight+div .e-menu {
        top: @top;
    }

    .editorInRight+div .e-code {
        left: @left;
        top: 4px+@top;
    }

    .editorInRight+div .e-preview {
        top: 4px+@top;
        left: @left2;
    }

    .editorInRight+div .e-trash {
        top: 6px+@top;
        left: @left3;
    }
}
@media (min-width:1770px) {
    @width: 690px;
    .editorInRight {
        max-width: @width;
        min-width: @width !important;
    }

    .w-e-toolbar {
        flex-wrap: wrap;
    }

    @top: 30px;
    @left: 48px;
    @gutter: 34px;
    @left2: @left+@gutter;
    @left3: @left2+@gutter;

    .editorInRight+div .e-menu {
        top: @top;
    }

    .editorInRight+div .e-code {
        left: @left;
        top: 4px+@top;
    }

    .editorInRight+div .e-preview {
        top: 4px+@top;
        left: @left2;
    }

    .editorInRight+div .e-trash {
        top: 6px+@top;
        left: @left3;
    }
}
@media (min-width:1920px) {
    @width: 800px;
    .editorInRight {
        max-width: @width;
        min-width: @width !important;
    }

    .w-e-toolbar {
        flex-wrap: wrap;
    }

    @top: 30px;
    @left: 48px;
    @gutter: 34px;
    @left2: @left+@gutter;
    @left3: @left2+@gutter;

    .editorInRight+div .e-menu {
        top: @top;
    }

    .editorInRight+div .e-code {
        left: @left;
        top: 4px+@top;
    }

    .editorInRight+div .e-preview {
        top: 4px+@top;
        left: @left2;
    }

    .editorInRight+div .e-trash {
        top: 6px+@top;
        left: @left3;
    }
}
</style>
